home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / sox.zip / BAND.C < prev    next >
C/C++ Source or Header  |  1992-06-15  |  3KB  |  132 lines

  1.  
  2. /*
  3.  * July 5, 1991
  4.  * Copyright 1991 Lance Norskog And Sundry Contributors
  5.  * This source code is freely redistributable and may be used for
  6.  * any purpose.  This copyright notice must be maintained. 
  7.  * Lance Norskog And Sundry Contributors are not responsible for 
  8.  * the consequences of using this software.
  9.  */
  10.  
  11. /*
  12.  * Sound Tools Bandpass effect file.
  13.  *
  14.  * Algorithm:  2nd order recursive filter.
  15.  * Formula stolen from MUSIC56K, a toolkit of 56000 assembler stuff.
  16.  * Quote:
  17.  *   This is a 2nd order recursive band pass filter of the form.                
  18.  *   y(n)= a * x(n) - b * y(n-1) - c * y(n-2)   
  19.  *   where :    
  20.  *        x(n) = "IN"           
  21.  *        "OUT" = y(n)          
  22.  *        c = EXP(-2*pi*cBW/S_RATE)             
  23.  *        b = -4*c/(1+c)*COS(2*pi*cCF/S_RATE)   
  24.  *   if cSCL=2 (i.e. noise input)               
  25.  *        a = SQT(((1+c)*(1+c)-b*b)*(1-c)/(1+c))                
  26.  *   else       
  27.  *        a = SQT(1-b*b/(4*c))*(1-c)            
  28.  *   endif      
  29.  *   note :     cCF is the center frequency in Hertz            
  30.  *        cBW is the band width in Hertz        
  31.  *        cSCL is a scale factor, use 1 for pitched sounds      
  32.  *   use 2 for noise.           
  33.  */
  34.  
  35. #include <math.h>
  36. #include "st.h"
  37.  
  38. /* Private data for Bandpass effect */
  39. typedef struct bandstuff {
  40.     float    center;
  41.     float    width;
  42.     double    A, B, C;
  43.     double    out1, out2;
  44.     short    noise;
  45.     /* 50 bytes of data, 52 bytes long for allocation purposes. */
  46. } *band_t;
  47.  
  48. /*
  49.  * Process options
  50.  */
  51. band_getopts(effp, n, argv) 
  52. eff_t effp;
  53. int n;
  54. char **argv;
  55. {
  56.     band_t band = (band_t) effp->priv;
  57.  
  58.     band->noise = 0;
  59.     if (n > 0 && !strcmp(argv[0], "-n")) {
  60.         band->noise = 1;
  61.         n--;
  62.         argv++;
  63.     }
  64.     if ((n < 1) || !sscanf(argv[0], "%f", &band->center))
  65.         fail("Usage: band [ -n ] center [ width ]");
  66.     band->width = band->center / 2;
  67.     if ((n >= 2) && !sscanf(argv[1], "%f", &band->width))
  68.         fail("Usage: band [ -n ] center [ width ]");
  69. }
  70.  
  71. /*
  72.  * Prepare processing.
  73.  */
  74. band_start(effp)
  75. eff_t effp;
  76. {
  77.     band_t band = (band_t) effp->priv;
  78.     if (band->center > effp->ininfo.rate/2)
  79.         fail("Band: center must be < minimum data rate/2\n");
  80.  
  81.     band->C = exp(-2*M_PI*band->width/effp->ininfo.rate);
  82.     band->B = -4*band->C/(1+band->C)*
  83.         cos(2*M_PI*band->center/effp->ininfo.rate);
  84.     if (band->noise)
  85.         band->A = sqrt(((1+band->C)*(1+band->C)-band->B *
  86.             band->B)*(1-band->C)/(1+band->C));
  87.     else
  88.         band->A = sqrt(1-band->B*band->B/(4*band->C))*(1-band->C);
  89.     band->out1 = band->out2 = 0.0;
  90. }
  91.  
  92. /*
  93.  * Processed signed long samples from ibuf to obuf.
  94.  * Return number of samples processed.
  95.  */
  96.  
  97. band_flow(effp, ibuf, obuf, isamp, osamp)
  98. eff_t effp;
  99. long *ibuf, *obuf;
  100. int *isamp, *osamp;
  101. {
  102.     band_t band = (band_t) effp->priv;
  103.     register counter, tablen;
  104.     int len, done;
  105.     register long mult;
  106.     register short *sinetab;
  107.     double d;
  108.     long l;
  109.  
  110.     len = ((*isamp > *osamp) ? *osamp : *isamp);
  111.  
  112.     /* yeah yeah yeah registers & integer arithmetic yeah yeah yeah */
  113.     for(done = 0; done < len; done++) {
  114.         l = *ibuf++;
  115.         d = (band->A * l - band->B * band->out1) - band->C * band->out2;
  116.         band->out2 = band->out1;
  117.         band->out1 = d;
  118.         *obuf++ = d;
  119.     }
  120. }
  121.  
  122. /*
  123.  * Do anything required when you stop reading samples.  
  124.  * Don't close input file! 
  125.  */
  126. band_stop(effp)
  127. eff_t effp;
  128. {
  129.     /* nothing to do */
  130. }
  131.  
  132.